package org.igeek.config.BeanPostProcessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.stream.Stream;

/**
 * @package org.igeek.config.BeanPostProcessor
 * @Description BeanPostProcessor bean的后置处理器 允许配置一个或者多个
 * @Author LittlePunk [296526219@qq.ccom]
 * @Version 2022.1
 * @Date 2023/11/14 15:15
 *
 * BeanPostProcessor接口： 提供在bean的初始化之前  初始化之后执行一些自定义逻辑
 *
 * 前提条件：如果想自定义后置处理器使用 需要加上@component注解
 */
@Component
public class MyAware implements BeanPostProcessor {
    /**
     * bean的初始化之前
     * @param bean  实例化bean
     * @param beanName  实例bean在IOC容器中的唯一标识
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //1.判断实例bean的类型 Tiger
        if(bean instanceof Tiger){
            //2.获取该类型上的所有属性
            Class<?> klass = bean.getClass();
            Field[] fields = klass.getDeclaredFields();
            //3.获取属性上是否有@MyAuto注解
            Stream.of(fields).filter(field -> field.isAnnotationPresent(MyAuto.class))
                    .forEach(field->{
                        String name = field.getDeclaredAnnotation(MyAuto.class).value();
                        String name1 = field.getName();
                        //System.out.println("name1 = " + name1);
                        //System.out.println("name = " + name);
                        //4.通过beanName 从IOC容器中 获取 相关的实例bean
                        Object obj = BeanUtils.getBean(name);
                        //5.通过反射 给当前属性赋值(破坏封装)
                        try {
                            field.setAccessible(true);
                            field.set(bean,obj);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    });
            //6.最后返回的是 修改后的bean
            System.out.println("初始化之后：bean="+bean+",beanName="+beanName);
            return bean;
        }


        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Dog){
            System.out.println("postProcessAfterInitialization Dog实例 初始化之后~~");
            return bean;
        }
        //System.out.println("postProcessAfterInitialization 初始化之后~~");
        return null;
    }
}
